#include"DatabaseWorker.h" 

#include"Song.h"

DatabaseWorker::DatabaseWorker(QSqlDatabase *db, QList<SongData*> songs, QObject *parent):QThread(parent){
	m_db = db;
	m_songs = songs;
}

DatabaseWorker::~DatabaseWorker(){
	m_db = 0;
}

void DatabaseWorker::addSongs(QList<SongData*> data){
	m_songs.append(data);
}

void DatabaseWorker::run(){
	char songData[4096];
	char buffer[4096];
	//Keep working until we handled all songs.
	while(m_songs.size()){
		m_changedArtists.insert(m_songs[0]->artist);
		SongData *prev = 0;
		bool first = true;
		QString queryString("REPLACE INTO song_data VALUES ");
		
		//Keep working until all songs belonging to one album are handled, or we're out of songs.
		while(m_songs.size() && (prev == 0 || m_songs[0]->album == prev->album )){
			SongData *song = m_songs.takeAt(0);
			m_currentSongs.push_back(song);//We don't want to lose this song, in case the SQL goes bad.

			//Add a separator if required.
			if(!first)
				queryString.append(", ");
			else
				first = false;
			
			//Append the query.
			_songData(song, songData, buffer, 4096);
			queryString.append(QString::fromUtf8(songData));//WARNING Static call is required to preserve special characters.
			//We need prev to compare albums (could have used m_currentSongs too, but meh).
			prev = song;
		}
		//Finish the SQL and compile it.
		queryString.append(";");
		
// 		printf("Should've finished album %s\n", prev->album.toUtf8().data());
		
		QSqlQuery query(queryString);
		if(!query.exec()){
			printf("Error adding songs to DB2: %s\n", queryString.toUtf8().data());
			_tryAgainOnError();
			continue;
		}
// 		printf("Executed: %s\n", queryString.toUtf8().data());
		while(m_currentSongs.size())
			delete m_currentSongs.takeAt(0);
	}
}

void DatabaseWorker::_songData(SongData *song, char *out, char *buf, int buflen){//Preserves special characters
	char *buffer = buf;
	int len = buflen;
	if(buf == 0 || buflen < 2048){
		buffer = new char[4096];
		len = 4096;
	}
	_safeString(song->title, buffer);
	_safeString(song->artist, buffer + (len/4));
	_safeString(song->album, buffer + (len/2));
	_safeString(song->path, buffer + (3*len/4));
	sprintf(out, "(%s, %s, %s, %d, %s)", buffer, buffer + (len/4), buffer + (len/2), song->trackno, buffer + (3*len/4));
	if(buf == 0 || buflen < 2048)
		delete [] buffer;
// 	printf("Built songdata %s\n", out);
}

void DatabaseWorker::_tryAgainOnError(){
	char queryString[4096];
	char titleString[1024];
	char artistString[1024];
	char albumString[1024];
	char pathString[1024];
	while(m_currentSongs.size()){
		SongData *song = m_currentSongs.takeAt(0);
		_safeString(song->title, titleString);
		_safeString(song->artist, artistString);
		_safeString(song->album, albumString);
		_safeString(song->path, pathString);
		sprintf(queryString, "REPLACE INTO song_data VALUES (%s, %s, %s, %d, %s);", titleString, artistString, albumString, song->trackno, pathString);
		printf("Remade query: %s\n", queryString);
		QSqlQuery query(queryString);
		if(!query.exec()){
			printf("Failed again: %s\n", queryString);
		}
	}
}

void DatabaseWorker::_safeString(const QString &string, char *out){//Preserves special characters...
	if(string.contains('\'') && string.contains('\"')){
		printf("DatabaseWorker::_safeString(%s), can't fix this :|\n", string.toUtf8().data());
		sprintf(out, "NULL");
	}else if(string.contains('\"'))
		sprintf(out, "\'%s\'", string.toUtf8().data());
	else
		sprintf(out, "\"%s\"", string.toUtf8().data());
// 	printf("Database::_safeString(%s)->%s\n", string.toUtf8().data(), out);
}

